import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockCondition {

    static class AlternateDemo{
        private int number = 1; //当前正在执行线程的标记
        private Lock lock = new ReentrantLock();
        private Condition condition1 = lock.newCondition();
        private Condition condition2 = lock.newCondition();
        private Condition condition3 = lock.newCondition();

        /**
         * @param totalLoop : 循环第几轮
         */
        public void loopA(int totalLoop){
            lock.lock();
            try {
                while (number != 1) condition1.await();
                for (int i = 1; i <= 1; i++) System.out.println(Thread.currentThread().getName() + "-" + i + "-" + totalLoop);
                number = 2;
                condition2.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void loopB(int totalLoop){
            lock.lock();
            try {
                while (number != 2) condition2.await();
                for (int i = 1; i <= 2; i++) System.out.println(Thread.currentThread().getName() + "-" + i + "-" + totalLoop);
                number = 3;
                condition3.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void loopC(int totalLoop){
            lock.lock();
            try {
                while (number != 3) condition3.await();
                for (int i = 1; i <= 3; i++) System.out.println(Thread.currentThread().getName() + "-" + i + "-" + totalLoop);
                number = 1;
                condition1.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        AlternateDemo ad = new AlternateDemo();
        int num = 5;

        new Thread(() -> {
            for (int i = 1; i <= num; i++) ad.loopA(i);
        }, "A").start();

        new Thread(() -> {
            for (int i = 1; i <= num; i++) ad.loopB(i);
        }, "B").start();

        new Thread(() -> {
            for (int i = 1; i <= num; i++) ad.loopC(i);
        }, "C").start();
    }

}
